/**
 ** 模拟数据输入的数据生成器
**/
module dataGenerator (
    input wire clk,
    input wire rst,
    input wire special_arbition,          //专用RAM的写仲裁结果信号
    input wire [15:0] special_idle,
    input wire common_arbition,            //组内通用RAM的写仲裁结果信号
    input wire [15:0] sram_write_en,
    input wire [3:0] group_memory_pick,         //RAM选择信号
    input wire [3:0] group_address_ready,       //RAM就绪信号
    input wire [15:0] address_ready,
    input wire [9:0] seed,
    output reg data_ready,
    output reg [31:0] data,               //数据
    output reg [5:0] data_priority,
    output reg [15:0] data_target_port,
    output reg data_write_en,
    output reg [9:0] data_size,
    output reg [5:0] group_priority,
    output reg [15:0] group_target_port,
    output reg group_write_en,
    output reg [9:0] group_size,
    output reg group_data_ready,
    output reg [31:0] group_data
);
    reg [3:0] history_memory_pick;
    reg [9:0] temp_size;
    reg [2:0] work_state; //工作状�??
    reg [5:0] temp_port;
    reg [9:0] history_size;
    reg [5:0] history_priority;
    reg [15:0] history_target_port;
    integer dataSeed;
    reg flag;

    //工作状�?�的转移逻辑
    always @(posedge clk) begin
        if (rst) begin
            //复位信号
            flag = 0;
            work_state = 3'b000;
            dataSeed <= seed;
            data_write_en <= 0;
            data_priority <= 0;
            data_target_port <= 0;
            data_ready <= 0;
            
            group_write_en <= 0;
            group_priority <= 0;
            group_target_port <= 0;
            group_data_ready <= 0;

            if (flag==0 && dataSeed>200 && dataSeed<300) begin
                history_size <= 64 + {$random(dataSeed)} % 65;
                history_target_port <= (1 << ({$random(dataSeed)} % 16));
                history_priority <= 1 + {$random(dataSeed)} % 7;
                flag <= 1;
                data_ready <= 0;
            end
        end
        else begin
            //初始状�?�发出请�?
            if (work_state == 3'b000) begin
                //如果对应的专用RAM处于空闲状�?�，发起仲裁信号
                if ((special_idle & history_target_port) > 0) begin
                    data_write_en <= 1;
                    data_priority <= history_priority;
                    data_target_port <= history_target_port;
                    data_size <= history_size;
                    work_state <= 3'b001;

                    group_write_en <= 0;
                    group_priority <= 0;
                    group_target_port <= 0;
                    group_data_ready <= 0;
                end
                
                //如果对应的专用RAM处于繁忙状�?�，则发起对于�?�用RAM的仲�?
                if ((special_idle & history_target_port) == 0) begin
                    data_write_en <= 0;
                    data_priority <= 0;
                    data_target_port <= 0;

                    //向组管理器发出写请求
                    group_write_en <= 1;
                    group_priority <= history_priority;
                    group_target_port <= history_target_port;
                    group_size <= history_size;
                    work_state <= 3'b101;
                end
            end
            
            //如果专用RAM的结果已经出了，并且处于专用RAM仲裁阶段
            if ((sram_write_en&history_target_port)>0 && work_state == 3'b001) begin
                //请求成功，进入下�?阶段
                if (special_arbition==1) begin
                    work_state <= 3'b010;
                end

                //请求失败，进入组管理器发送阶�?
                if (special_arbition==0) begin
                    data_write_en <= 0;
                    data_priority <= 0;
                    data_target_port <= 0;
                    //向组管理器发出写请求
                    group_write_en <= 1;
                    group_priority <= history_priority;
                    group_target_port <= history_target_port;
                    group_size <= history_size;
                    work_state <= 3'b101;
                end
            end
            
            //如果通用RAM仲裁阶段，专用RAM就绪，则尝试使用专用RAM
            if (common_arbition==0 && work_state==3'b101 && (special_idle&history_target_port)>0) begin
                data_write_en <= 1;
                data_priority <= history_priority;
                data_target_port <= history_target_port;
                data_size <= history_size;
                work_state <= 3'b001;

                group_write_en <= 0;
                group_priority <= 0;
                group_target_port <= 0;
                group_data_ready <= 0;
            end

            
            //组管理器竞争成功，则使用通用RAM写入
            if (common_arbition==1 && work_state == 3'b101 && group_memory_pick>0) begin
                history_memory_pick <= group_memory_pick;
                work_state <= 3'b110;
            end

            //获取到了专用RAM的地�?就绪命令，开始向专用RAM传输数据
            if (work_state == 3'b010) begin
                if ((address_ready & history_target_port)>0) begin
                    temp_size <= history_size;
                    //�?始传输数�?
                    data_write_en <= 0;
                    data_priority <= 0;
                    data_target_port <= 0;
                    work_state <= 3'b011;
                end
            end


            //获取到了通用RAM的地�?就绪命令，开始向通用RAM传输数据
            if (work_state == 3'b110) begin
                if ((group_address_ready & history_memory_pick)>0) begin
                    temp_size <= history_size;
                    //�?始传输数�?
                    group_write_en <= 0;
                    group_priority <= 0;
                    work_state <= 3'b111;
                end
            end

            //专用RAM数据发�?�完�?
            if (work_state ==3'b111) begin
                if (temp_size == 1) begin
                    //�?后一个字的数据发送完毕，修改工作状�?�为空闲，可以处理其他内�?
                    work_state <= 3'b000;
                    group_data_ready <= 1'b0;
                    group_data <= 0;
                    history_size <= 64 + {$random(dataSeed)} % 65;
                    history_target_port <= (1 << ({$random(dataSeed)} % 16));
                    history_priority <= 1 + {$random(dataSeed)} % 7;
                end
                else begin
                    //继续发�?�数�?
                    group_data_ready <= 1'b1;
                    group_data <= 64 + {$random(dataSeed)} % 449;
                end

                temp_size <= temp_size - 1;
            end

            if (work_state == 3'b011) begin
                if (temp_size == 1) begin
                    //�?后一个字的数据发送完毕，修改工作状�?�为空闲，可以处理其他内�?
                    work_state <= 3'b000;
                    data_ready <= 1'b0;
                    data <= 0;
                    history_size <= 64 + {$random(dataSeed)} % 65;
                    history_target_port <= (1 << ({$random(dataSeed)} % 16));
                    history_priority <= 1 + {$random(dataSeed)} % 7;
                end
                else begin
                    //继续发�?�数�?
                    data_ready <= 1'b1;
                    data <= 64 + {$random(dataSeed)} % 449;
                end

                temp_size <= temp_size - 1;
            end
        end
    end
endmodule